package com.bbex.controller;


import com.bbex.config.sercurity.RedisSessionUser;
import com.bbex.constant.Constants;
import com.bbex.constant.SercurityConstant;
import com.bbex.pojo.GlobalMessageResponseVo;
import com.bbex.pojo.ResponsePage;
import com.bbex.service.CoinService;
import com.bbex.service.DictService;
import com.bbex.service.EntActivityService;
import com.bbex.service.ShareService;
import com.bbex.util.RsaUtils;
import com.bbex.vo.RandomValidateVO;
import com.bbex.vo.UserStatisticsInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Title :
 * Description : 共享兑换管理
 * Copyright (C) zw.FinTec
 *
 * @author department:研发部
 * @version 修改历史:
 * 修改人 修改日期 修改描述
 * -------------------------------------------<
 */
@Controller
@RequestMapping("/bbuni/convel")
public class ConverLevelController {
    @Autowired
    private ShareService shareService;
    @Autowired
    private CoinService coinService;
    @Autowired
    private DictService dictService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Resource(name = "stringRedisTemplate")
    ValueOperations<String, String> valOpsStr;
    /**
     * 共享兑换数据显示接口
     *
     * @return
     */
    @RequestMapping("/getShareMessage")
    @ResponseBody
    public Mono getShareMessage() {
        Map map = new HashMap();
        map = shareService.getShareMessage();
        return Mono.just(GlobalMessageResponseVo.newSuccessInstance(map));
    }

    /**
     * 共享兑换接口
     *
     * @return
     */

    @RequestMapping("/convelShare")
    @ResponseBody
    public Mono<GlobalMessageResponseVo> convelShare(RandomValidateVO randomValidateVO)  {
        Mono<SecurityContext> context= ReactiveSecurityContextHolder.getContext();
        return context.filter(c -> Objects.nonNull(c.getAuthentication()))
                .map(s -> s.getAuthentication().getPrincipal())
                .cast(RedisSessionUser.class)
                .map(e -> {
                    String userId=e.getId();
                    String mobile=e.getMobile();
                    String mail=e.getMail();
                    try {
                        //交易密码
                        if(StringUtils.isBlank(e.getExPassword())) {
                            return GlobalMessageResponseVo.newInstance(Constants.EX_PASSWORD,"请设置交易密码");
                        }
                        String decryPassword = RsaUtils.decryptByPrivateKey(randomValidateVO.getExCode(), RsaUtils.DEFAULT_PRIVATE_KEY);
                        if(StringUtils.isBlank(decryPassword)) {
                            return GlobalMessageResponseVo.newErrorInstance("请填写交易密码");
                        }
                        if(!passwordEncoder.matches(decryPassword, e.getExPassword())) {
                            return GlobalMessageResponseVo.newErrorInstance("交易密码不正确");
                        }
                        //设置交易密码验证码2小时失效
                        String authKeyEx = SercurityConstant.AUTH_USERNAME_REDIS_NAMESAPCE+"ex:" + e.getUsername();
                        valOpsStr.set(authKeyEx, SercurityConstant.AuthType.PASS_AUTH.getCode(), SercurityConstant.REDIS_EXPIRE_TIME_ONE_HOUR * 2, TimeUnit.SECONDS);
                        if(randomValidateVO.getEthVolume().compareTo(new BigDecimal("30"))==1){
                            return GlobalMessageResponseVo.newSuccessInstance("每次兑换量不得超过30个");
                        }
                        if(randomValidateVO.getEthVolume().compareTo(new BigDecimal("0.1"))==-1){
                            return GlobalMessageResponseVo.newSuccessInstance("每次兑换量不得小于0.1个");
                        }
                        List<Map> serNumList = dictService.getDictDetailByItemCode("serVolume");
                        //矿工费
                        BigDecimal serNum=new BigDecimal(serNumList.get(0).get("dictName").toString());
                        //查看个人ETH总量
                        Map coinMap = coinService.findByuserId(userId,randomValidateVO.getEthId());
                        BigDecimal coinNum = new BigDecimal(coinMap.get("volume").toString());
                        //判断个人ETH总量是否大于等于兑换所需ETH总量
                        BigDecimal ethNum = randomValidateVO.getEthVolume().add(serNum);
                        if (coinNum.compareTo(ethNum)>-1) {
                            shareService.convelShare(mobile,mail,randomValidateVO.getHmId(),randomValidateVO.getEthId(),userId,randomValidateVO.getEthVolume(),serNum);
                            return GlobalMessageResponseVo.newSuccessInstance("交互成功");
                        } else {
                            return GlobalMessageResponseVo.newSuccessInstance("可用余额不足");
                        }
                    }catch (Exception E){
                        return GlobalMessageResponseVo.newSuccessInstance("交互失败");
                    }
                });
    }


    /**
     * 共享兑换排行榜接口
     *
     * @return
     */

    @RequestMapping("/getRankInfo")
    @ResponseBody
    public Mono getRankInfo() {
        List<Map> list = shareService.getRankInfo();
        return Mono.just(GlobalMessageResponseVo.newSuccessInstance(list));
    }


    /**
     * 个人共享兑换记录接口
     *
     * @return
     */
    @RequestMapping("/getPersonRankInfo")
    @ResponseBody
    public Mono getPersonRankInfo(UserStatisticsInfoVO infoVO) {
        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();
        return context.filter(c -> Objects.nonNull(c.getAuthentication()))
                .map(s -> s.getAuthentication().getPrincipal())
                .cast(RedisSessionUser.class)
                .map(e -> {
                    infoVO.setUserId(e.getId());
                    ResponsePage<Map> result =shareService.getPersonRankInfo(infoVO);

                    return GlobalMessageResponseVo.newSuccessInstance(result);

                });

    }



}
